#include <stdio.h>
#include "../include/define.h"
#include "../include/main.h"

#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  
	int command=DEFAULT_GAME;
	
	char * elementsFile = "src/resources/myelements.name";
	char * magicFile= "src/resources/myelements.magic";
	
	char * elementArg;
	
	int i;
	
	
	for(i=0; i<argc && command==DEFAULT_GAME;i++) {
                if (strcmp(argv[i], "-n") == 0){
			if(argv[i + 1] != NULL){
				elementsFile = argv[i + 1];
				i++;
			}
		} else if (strcmp(argv[i], "-m") == 0){
			if(argv[i + 1] != NULL){
				magicFile = argv[i + 1];
				i++;
			}
		} else if (strcmp(argv[i], "-t") == 0){
                        command=TERMINAL_ELEMENTS;
		} else if (strcmp(argv[i], "-h") == 0){
                        command=HELP_DIALOG;
		} else if (strcmp(argv[i], "-e") == 0) {
			if(argv[i + 1] != NULL) {
				elementArg = getElementArg(argv, i+1);
				if(elementArg!=NULL)
					command=ROOT_ELEMENT;
			}
                } else if (strcmp(argv[i], "-b") == 0) {
			if(argv[i + 1] != NULL){
				elementArg = getElementArg(argv, i+1);
				if(elementArg!=NULL)
					command=BASIC_ELEMENTS;
			}
                }

        }
        
	int cantMagics;
	elements = getElements(elementsFile);
	if(elements!=NULL){
		magics = getMagics(magicFile,&cantMagics);
			if(magics==NULL){	
				printf("Error en los archivos!\n");
				return;
			}
	}else{	
		printf("Error en los archivos!\n");
		return;
	}
	
	 switch(command){
	    case DEFAULT_GAME: 		game();break;
	    case TERMINAL_ELEMENTS:	terminalElements();break;
	    case HELP_DIALOG: 		helpDialog();break;
	    case ROOT_ELEMENT: 		rootElement(elementArg, cantMagics);break;
	    case BASIC_ELEMENTS: 	basicElements(elementArg, cantMagics);break;
	    default:break;
	 }
		
	  
}

char * getElementArg(char *argv[], int i){
	char resp[MAX_ELEMENT_NAME] = {'\0'};
	char * aux = malloc(sizeof(char *) * (MAX_ELEMENT_NAME + 1));
	int j;
  
	while( argv[i]!=NULL && strncmp(argv[i], "-", 1)!=0 
	  && strncmp(argv[i], "<", 1)!=0 && strncmp(argv[i], ">", 1)!=0){
	  	strcat(resp-1, " ");
		strcat(resp, argv[i]);
		i++;
	}
	for(j = 0 ;j < MAX_ELEMENT_NAME; j++) {
		aux[j] = resp[j];
	}
	
	for(i = 0; aux[i] == ' '; i++);
	
	for(j = 0; aux[j] != '\0'; j++) {
		aux[j] = aux[j + i];
	}
	
	return aux;
}

void terminalElements(){
  
	Element * terminales;
	terminales = malloc((sizeof(terminales) + 1) * sizeof(Element));
	int cantT=0;
	int i, j, flag;
	for(i = 0; elements[i].name != NULL ; i++) {
		flag=1;
		if(magics!=NULL)
			for(j = 0; magics[j].generated != NULL && flag; j ++) {
				if( (strcmp(magics[j].e1->name, elements[i].name)==0) || (strcmp(magics[j].e2->name, elements[i].name)==0))
					flag=0;
			}
		if(flag){
			  
			  terminales = realloc(terminales, (cantT + 2) * sizeof(Element));
			  agregarElemento(terminales, elements[i].name, &cantT);
			  terminales[cantT].name=NULL;
		}
	}
	
	if(cantT>0){
		ordenaAlfa(terminales, cantT);
		printf("ELEMENTOS TERMINALES:\n");
		for(i = 0; terminales[i].name != NULL ; i++) {
			printf("%s\n", terminales[i].name);
		}
	}else
		printf("No hay elementos terminales\n");
		
}

void ordenaAlfa(Element * terminales, int cantT){
  
	Element  aux;
	int i, j;
	int k=0;
	for(j=0; j< cantT;j++){
		for(i=0; i< cantT-k-1; i++){
			if(strcmp(terminales[i].name, terminales[i+1].name)>0){
				aux=terminales[i+1];
				terminales[i+1]=terminales[i];
				terminales[i]=aux;
			}
		}
		k++;
	}  
}

void helpDialog(){
	printf("AYUDA:\n");
	printf("Debe ingresar los dos elementos que desea combinar separados por un '+'\n");
	printf("Ejemplo:	fire + water\n");
	printf("Estos elementos puden ser basicos o derivados\n");
	int i;
	printf("ELEMENTOS BASICOS:\n");
	
	if(basics!=NULL){
		for(i = 0; basics[i].name != NULL ; i++) {
			printf("*	%s\n", basics[i].name);
		}
	}else	printf("No hay elementos basicos\n"); 
	
	printf("\n");  
}

void rootElement(char * element, int cant){
	int i;
	Element * repetidos;
	repetidos = malloc((sizeof(repetidos) + 1)*cant* sizeof(Element));
	
	Element * resp;
	resp = malloc((sizeof(resp) + 1) *100* sizeof(Element));
	
	for(i=0; magics[i].generated!=NULL;i++){
		if(strcmp(element, magics[i].e1->name)==0 || strcmp(element, magics[i].e2->name)==0){
			recursiveRoot(magics[i].generated->name, repetidos, resp);
		}	  
	}
	
	if(cantResp>0){
		ordenaAlfa(resp, cantResp);
		for(i = 0; resp[i].name != NULL ; i++) {
			printf("%s\n", resp[i].name);
		}
	}else{
		printf("El elemento \"%s\" no existe o es terminal\n", element);
	}
	
	free(repetidos);
	cantRep=0;
	free(resp);
	cantResp=0;
  
}

void recursiveRoot(char * element, Element * repetidos, Element* resp){
  
	if(estaRepetido(repetidos, element)){
		return;
	}
	
	agregarElemento(resp, element, &cantResp);
	
	agregarElemento(repetidos, element, &cantRep);
	
	int i;	 
	for(i=0; magics[i].generated!=NULL;i++){
		if(strcmp(element, magics[i].e1->name)==0 || strcmp(element, magics[i].e2->name)==0){
			recursiveRoot(magics[i].generated->name, repetidos, resp);
		}	  
	}
	 
}


void basicElements(char * elementArg, int cant){
	
	Element * repetidos;
	repetidos = malloc((sizeof(repetidos) + 1) *cant* sizeof(Element));
	
	Element * resp;
	resp = malloc((sizeof(resp) + 1) *100 *sizeof(Element));
	
	recursiveBasics(elementArg, repetidos, resp);
	
	int i;
	if(cantResp>0){
		ordenaAlfa(resp, cantResp);
		for(i = 0; resp[i].name != NULL ; i++) {
			printf("%s\n", resp[i].name);
		}
	}else {
		printf("El elemento \"%s\" no existe\n", elementArg);
	}
	
	free(repetidos);
	cantRep=0;
	free(resp);
	cantResp=0;
  
}

void recursiveBasics(char * element, Element * repetidos, Element* resp){
	if(estaRepetido(repetidos, element)){
		return;
	}
	
	agregarElemento(repetidos, element, &cantRep);
	
	int i=0;	 
	for(i=0; magics[i].generated!=NULL;i++){
		if(strcmp(element, magics[i].generated->name)==0){
			if(strcmp("-1", magics[i].e1->name)==0){
				agregarElemento(resp, element, &cantResp);
			}else{
				recursiveBasics(magics[i].e1->name, repetidos, resp);
				recursiveBasics(magics[i].e2->name, repetidos, resp);
			}
		}
	  
	}
	 
}
void agregarElemento(Element * array, char * elemento, int* cant){
  	array[*cant].name = malloc(sizeof(elemento + 1) * sizeof(char));
	strcpy(array[*cant].name, elemento);			  
	*cant =*cant+1;
  
}
int estaRepetido(Element * repetidos, char * element){
	int i;	
	for(i=0; repetidos[i].name!=NULL;i++)
			if(strcmp(element, repetidos[i].name)==0)
				return 1;
	return 0;
}
	
void printNames() {
	int i;
	printf("Element names: \n\n");
	for(i = 0; elements[i].name != NULL ; i++) {
		printf("%s\n", elements[i].name);
	}
}

void printMagics() {
	int i;
	printf("***************************************************************\n");
	printf("Magics: \n\n");
	if(magics!=NULL){
		for(i = 0; magics[i].generated != NULL; magics ++) {
			printf("%s = %s + %s\n", magics[i].generated->name, magics[i].e1->name, magics[i].e2->name);
		}
	}else	printf("No hay magias...\n");
	      
	printf("***************************************************************\n");
}
